package org.px.gui;

import org.px.domain.LeaveRecord;
import org.px.service.LeaveRecordService;

import com.toedter.calendar.JDateChooser;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;

public class ApplyLeaveFrame extends JFrame {
    private JComboBox<String> leaveTypeCombo;
    private JDateChooser startDateChooser;
    private JDateChooser endDateChooser;
    private JSpinner startTimeSpinner;
    private JSpinner endTimeSpinner;
    private JTextField reasonField;
    private LeaveRecordService leaveRecordService = new LeaveRecordService();
    private String empId;

    public ApplyLeaveFrame(JFrame parent, String empId) {
        this.empId = empId;
        initUI();
        setLocationRelativeTo(parent);
    }

    private void initUI() {
        setTitle("员工请假管理系统 - 申请请假");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 10, 10);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 请假类型标签和下拉框
        gbc.gridx = 0;
        gbc.gridy = 0;
        panel.add(new JLabel("请假类型:"), gbc);

        gbc.gridx = 1;
        leaveTypeCombo = new JComboBox<>(new String[]{"事假", "病假", "年假", "婚假", "产假"});
        leaveTypeCombo.setPreferredSize(new Dimension(200, 30));
        panel.add(leaveTypeCombo, gbc);

        // 开始时间日期选择
        gbc.gridx = 0;
        gbc.gridy = 1;
        panel.add(new JLabel("开始日期:"), gbc);

        gbc.gridx = 1;
        startDateChooser = new JDateChooser();
        startDateChooser.setDateFormatString("yyyy-MM-dd");
        panel.add(startDateChooser, gbc);

        // 开始时间时间选择
        gbc.gridx = 2;
        startTimeSpinner = new JSpinner(new SpinnerDateModel());
        JSpinner.DateEditor startTimeEditor = new JSpinner.DateEditor(startTimeSpinner, "HH:mm");
        startTimeSpinner.setEditor(startTimeEditor);
        panel.add(startTimeSpinner, gbc);

        // 结束时间日期选择
        gbc.gridx = 0;
        gbc.gridy = 2;
        panel.add(new JLabel("结束日期:"), gbc);

        gbc.gridx = 1;
        endDateChooser = new JDateChooser();
        endDateChooser.setDateFormatString("yyyy-MM-dd");
        panel.add(endDateChooser, gbc);

        // 结束时间时间选择
        gbc.gridx = 2;
        endTimeSpinner = new JSpinner(new SpinnerDateModel());
        JSpinner.DateEditor endTimeEditor = new JSpinner.DateEditor(endTimeSpinner, "HH:mm");
        endTimeSpinner.setEditor(endTimeEditor);
        panel.add(endTimeSpinner, gbc);

        // 原因标签和输入框
        gbc.gridx = 0;
        gbc.gridy = 4;
        panel.add(new JLabel("原因:"), gbc);

        gbc.gridx = 1;
        reasonField = new JTextField(20);
        panel.add(reasonField, gbc);

        // 提交按钮
        gbc.gridx = 0;
        gbc.gridy = 5;
        gbc.gridwidth = 2;
        JButton submitBtn = new JButton("提交申请");
        submitBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                submitLeaveApplication();
            }
        });
        panel.add(submitBtn, gbc);

        add(panel);
    }

    private void submitLeaveApplication() {
        String leaveType = (String) leaveTypeCombo.getSelectedItem();
        // 获取日期和时间组件值
        java.util.Date startDate = startDateChooser.getDate();
        java.util.Date startTime = (java.util.Date) startTimeSpinner.getValue();
        java.util.Date endDate = endDateChooser.getDate();
        java.util.Date endTime = (java.util.Date) endTimeSpinner.getValue();

        // 合并日期和时间
        Timestamp startTimestamp = new Timestamp(combineDateTime(startDate, startTime).getTime());
        Timestamp endTimestamp = new Timestamp(combineDateTime(endDate, endTime).getTime());

        String reason = reasonField.getText().trim();

        if (leaveType.isEmpty() || startDate == null || startTime == null || endDate == null || endTime == null || reason.isEmpty()) {
            JOptionPane.showMessageDialog(this, "所有字段均不能为空", "申请错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 时间有效性校验
        if (startDate.after(endDate)) {
            JOptionPane.showMessageDialog(this, "开始时间不能晚于结束时间", "时间错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        try {
            // 计算实际持续时间（单位：天）
            long diff = endTimestamp.getTime() - startTimestamp.getTime();
            float days = (float) diff / (1000 * 60 * 60 * 24);
            
            LeaveRecord leaveRecord = new LeaveRecord();
            leaveRecord.setEmp_id(empId);
            leaveRecord.setLeave_type(leaveType);
            leaveRecord.setStart_time(startTimestamp);
            leaveRecord.setEnd_time(endTimestamp);
            leaveRecord.setDuration(days);  // 自动计算持续时间
            leaveRecord.setReason(reason);

            if (leaveRecordService.addLeaveRecord(leaveRecord)) {
                JOptionPane.showMessageDialog(this, "请假申请提交成功", "提示", JOptionPane.INFORMATION_MESSAGE);
                dispose();
            } else {
                JOptionPane.showMessageDialog(this, "请假申请提交失败，请重试", "申请错误", JOptionPane.ERROR_MESSAGE);
            }
        } catch (IllegalArgumentException ex) {
            JOptionPane.showMessageDialog(this, "时间格式错误，请使用 yyyy-MM-dd HH:mm 格式", "申请错误", JOptionPane.ERROR_MESSAGE);
        } catch (SQLException ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "数据库操作异常：" + ex.getMessage(), "系统错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    // 日期时间合并方法
    private java.util.Date combineDateTime(java.util.Date date, java.util.Date time) {
        Calendar dateCal = Calendar.getInstance();
        dateCal.setTime(date);
        
        Calendar timeCal = Calendar.getInstance();
        timeCal.setTime(time);
        
        dateCal.set(Calendar.HOUR_OF_DAY, timeCal.get(Calendar.HOUR_OF_DAY));
        dateCal.set(Calendar.MINUTE, 0);
        dateCal.set(Calendar.SECOND, 0);  // 新增秒数归零
        return dateCal.getTime();
    }
}